Refactor domain/vcpu allocation to be more separated.
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 12 Oct 2005 16:01:38 +0000 (17:01 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 12 Oct 2005 16:01:38 +0000 (17:01 +0100)
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/domain_build.c
xen/common/dom0_ops.c
xen/common/domain.c
xen/common/schedule.c
xen/include/xen/sched.h

index bf8129a5722c2a08927de76a486d6394ad38cdd4..69b0ddd58b61959fc91dbdc4a65941809ba4db61 100644 (file)
@@ -560,7 +560,7 @@ int construct_dom0(struct domain *d,
     d->shared_info->n_vcpu = num_online_cpus();
 
     for ( i = 1; i < d->shared_info->n_vcpu; i++ )
-        (void)alloc_vcpu(d, i);
+        (void)alloc_vcpu(d, i, i % num_online_cpus());
 
     /* Set up monitor table */
     update_pagetables(v);
index e6ffa594381e0463f109b55ee3d03df2674abfff..458255d3dbbacef86c9f92ae45a065046ddc10fd 100644 (file)
@@ -224,7 +224,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
     case DOM0_MAX_VCPUS:
     {
         struct domain *d;
-        unsigned int i, max = op->u.max_vcpus.max;
+        unsigned int i, max = op->u.max_vcpus.max, cpu;
 
         ret = -EINVAL;
         if ( max > MAX_VIRT_CPUS )
@@ -250,8 +250,14 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
 
         ret = -ENOMEM;
         for ( i = 0; i < max; i++ )
-            if ( (d->vcpu[i] == NULL) && (alloc_vcpu(d, i) == NULL) )
-                goto maxvcpu_out;
+        {
+            if ( d->vcpu[i] == NULL )
+            {
+                cpu = (d->vcpu[i-1]->processor + 1) % num_online_cpus();
+                if ( alloc_vcpu(d, i, cpu) == NULL )
+                    goto maxvcpu_out;
+            }
+        }
 
         ret = 0;
 
index 1627c97a755724b48182196442dc13323056a6f1..96c3b0a083c8e6625ce6e58f6b6b1dafe4e620c7 100644 (file)
@@ -36,16 +36,11 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu)
     if ( (d = alloc_domain()) == NULL )
         return NULL;
 
-    v = d->vcpu[0];
+    d->domain_id = dom_id;
 
     atomic_set(&d->refcnt, 1);
-    atomic_set(&v->pausecnt, 0);
-
-    d->domain_id = dom_id;
-    v->processor = cpu;
 
     spin_lock_init(&d->big_lock);
-
     spin_lock_init(&d->page_alloc_lock);
     INIT_LIST_HEAD(&d->page_list);
     INIT_LIST_HEAD(&d->xenpage_list);
@@ -63,10 +58,16 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu)
         return NULL;
     }
     
+    if ( (v = alloc_vcpu(d, 0, cpu)) == NULL )
+    {
+        grant_table_destroy(d);
+        evtchn_destroy(d);
+        free_domain(d);
+        return NULL;
+    }
+
     arch_do_createdomain(v);
     
-    sched_add_domain(v);
-
     if ( !is_idle_task(d) )
     {
         write_lock(&domlist_lock);
@@ -370,8 +371,6 @@ int boot_vcpu(struct domain *d, int vcpuid, struct vcpu_guest_context *ctxt)
     if ( (rc = arch_set_info_guest(v, ctxt)) != 0 )
         return rc;
 
-    sched_add_domain(v);
-
     return rc;
 }
 
index e45c7f6582a7f9b8bb314b7a3faa47442e4d07e8..4c58a8d68e950b16739e918011d0b18677991719 100644 (file)
@@ -93,7 +93,8 @@ void free_domain(struct domain *d)
     xfree(d);
 }
 
-struct vcpu *alloc_vcpu(struct domain *d, unsigned int vcpu_id)
+struct vcpu *alloc_vcpu(
+    struct domain *d, unsigned int vcpu_id, unsigned int cpu_id)
 {
     struct vcpu *v;
 
@@ -104,6 +105,7 @@ struct vcpu *alloc_vcpu(struct domain *d, unsigned int vcpu_id)
 
     v->domain = d;
     v->vcpu_id = vcpu_id;
+    v->processor = cpu_id;
     atomic_set(&v->pausecnt, 0);
     v->cpumap = CPUMAP_RUNANYWHERE;
 
@@ -116,18 +118,14 @@ struct vcpu *alloc_vcpu(struct domain *d, unsigned int vcpu_id)
         return NULL;
     }
 
-    if ( vcpu_id == 0 )
-        return v;
+    sched_add_domain(v);
 
-    v->vcpu_info = &d->shared_info->vcpu_data[vcpu_id];
-
-    d->vcpu[v->vcpu_id-1]->next_in_list = v;
-
-    v->processor = (d->vcpu[0]->processor + 1) % num_online_cpus();
-    if ( test_bit(_VCPUF_cpu_pinned, &d->vcpu[0]->vcpu_flags) )
-        set_bit(_VCPUF_cpu_pinned, &v->vcpu_flags);
-
-    set_bit(_VCPUF_down, &v->vcpu_flags);
+    if ( vcpu_id != 0 )
+    {
+        v->vcpu_info = &d->shared_info->vcpu_data[vcpu_id];
+        d->vcpu[v->vcpu_id-1]->next_in_list = v;
+        set_bit(_VCPUF_down, &v->vcpu_flags);
+    }
 
     return v;
 }
@@ -136,19 +134,10 @@ struct domain *alloc_domain(void)
 {
     struct domain *d;
 
-    if ( (d = xmalloc(struct domain)) == NULL )
-        return NULL;
-    
-    memset(d, 0, sizeof(*d));
-
-    if ( alloc_vcpu(d, 0) == NULL )
-        goto out;
+    if ( (d = xmalloc(struct domain)) != NULL )
+        memset(d, 0, sizeof(*d));
 
     return d;
-
- out:
-    xfree(d);
-    return NULL;
 }
 
 /*
index 61ae51c576a8bc3558e5e41e95ed0f54e10c4a61..6f8a43d3843be0c99e4972e3c23a2d094d79a386 100644 (file)
@@ -167,7 +167,8 @@ extern struct vcpu *idle_task[NR_CPUS];
 #define IDLE_DOMAIN_ID   (0x7FFFU)
 #define is_idle_task(_d) (test_bit(_DOMF_idle_domain, &(_d)->domain_flags))
 
-struct vcpu *alloc_vcpu(struct domain *d, unsigned int vcpu_id);
+struct vcpu *alloc_vcpu(
+    struct domain *d, unsigned int vcpu_id, unsigned int cpu_id);
 
 struct domain *alloc_domain(void);
 void free_domain(struct domain *d);